package com.zhihao.zhihaopicturebackend.utils;

import cn.hutool.core.thread.ThreadFactoryBuilder;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zhihao.zhihaopicturebackend.model.entity.ServicePicture;

import java.util.concurrent.*;
import java.util.function.Function;

/**
 * @author Jackson
 * @create 2024/12/30 14:38
 * @description 异步更新图片查询次数工具类
 */
public class PictureQueryTimesThreadPool {

    /** 核心线程数 */
    public static final int THREAD_POOL_SIZE = 10;

    /** 最大线程数 */
    public static final int THREAD_POOL_MAX_SIZE = 15;

    /** 多余线程(最大线程数-核心线程数)的保活时间 */
    public static final int THREAD_KEEP_ALIVE_TIME = 10;

    /** 线程池执行器  */
    private static ExecutorService ThreadPoolExecutor = new ThreadPoolExecutor(
            THREAD_POOL_SIZE,   // 核心线程数
            THREAD_POOL_MAX_SIZE,   // 最大线程数(=核心线程数：固定线程池 >核心线程数：可变线程,初始为core,后续可扩展max)
            THREAD_KEEP_ALIVE_TIME,                // 保活时间
            TimeUnit.SECONDS,
            new LinkedBlockingDeque<>(512), // 双端阻塞队列
//            Executors.defaultThreadFactory(),
            // 创建自定义的图片异步线程创建的线程工厂(便于异步线程日志的查询)
            ThreadFactoryBuilder.create().setNamePrefix("PictureQueryTimesUpdate").build(),
            new ThreadPoolExecutor.AbortPolicy()
    );

    /**
     * 图片查询字段更新异步执行
     * @author Jackson
     * @date 2024-12-30 15:12
     * @return Long
     **/
    public static void pictureQueryTimesRequest(Page picturePage, Function<Page<ServicePicture>, Long> func) {
        CompletableFuture.supplyAsync(() -> {
            try {
                // 模拟处理时间
                Thread.sleep(60 * 1000); // 60s
                return func.apply(picturePage);
            } catch (InterruptedException e) {
                throw new IllegalStateException(e);
            }
        }, ThreadPoolExecutor);
    }


    /**
     * sleep等待,单位为毫秒
     */
    public static void sleep(long milliseconds)
    {
        try
        {
            Thread.sleep(milliseconds);
        }
        catch (InterruptedException e)
        {
            return;
        }
    }

}
